%  =======================================================================================================================================================
% 
%  Code Description: 
%  This codefile applies the methodology in Section 4 to the sample of German investment funds.
% 
%  =======================================================================================================================================================
% 
%  Major output:
%  - dataset underlying the results in Section 4.
%  =======================================================================================================================================================
% 
%  General disclaimer:
%  This file directory produces replication code for "Connected Funds". 
%  Because we cannot share the underlying data provided by the Bundesbank's Research Data and Service Centre (RDSC) and other subscription data sources, 
%  we have included pseudo data to show how the raw data are formatted. 
%  Other researchers can go through a similar approval and subscription process to obtain the underlying data. (2023-04-06)
% 
%  =======================================================================================================================================================

clear all;
close all;

projectPath = 'C:\ConnectedFunds_Codebase\'

% Add functions folders
addpath(strcat(projectPath, 'Code\matlab_functions'));

load(strcat(projectPath, 'Data\CrossholdingsMatter\CrossHoldingsMatter_OverTime.mat'), 'umonth');

% load asset level results
for t = 1:length(umonth)
    load(strcat(projectPath, 'Data\CrossholdingsMatter\tmp_Lookthrough_',num2str(umonth(t))),'tmp');
    
    if t == 1
      All_Results = tmp;
    else
      All_Results = [All_Results; tmp]; 
    end
    
    clear tmp*
    
end

load(strcat(projectPath, 'Data\CSDB\CSDB_Returns'));

[~,idx] = ismember(uwpkenn_all,unique(All_Results.ISIN));
CSDB_AccInterest(:,idx==0) = [];
CSDB_AccInterest_EUR(:,idx==0) = [];
CSDB_Coupon(:,idx==0) = [];
CSDB_Coupon_EUR(:,idx==0) = [];
CSDB_Dividend(:,idx==0) = [];
CSDB_Dividend_EUR(:,idx==0) = [];
CSDB_Price(:,idx==0) = [];
CSDB_Price_EUR(:,idx==0) = [];
CSDB_Volume(:,idx==0) = [];
CSDB_Volume_EUR(:,idx==0) = [];
CSDB_Yield(:,idx==0) = [];

uwpkenn_all(idx == 0) = [];
clear idx

Nisins = length(uwpkenn_all);
Tmonth = length(umonth);

winsorize_percentile = 0.01;

% calculate asset-level returns, based on clean prices
CSDB_Return_CleanPrice_EUR = [NaN(1,Nisins); diff(CSDB_Price_EUR)./CSDB_Price_EUR(1:Tmonth-1,:)];

% calculate asset-level returns, based on dirty prices
CSDB_DirtyPrice1_EUR    = NaN(Tmonth,Nisins);
CSDB_DirtyPrice2_EUR    = NaN(Tmonth,Nisins);

for t = 1:Tmonth                  
   CSDB_DirtyPrice1_EUR(t,:) = nansum([CSDB_Price_EUR(t,:); ...
                                       CSDB_AccInterest_EUR(t,:)])';
   CSDB_DirtyPrice2_EUR(t,:) = nansum([CSDB_Price_EUR(t,:); ...
                                       CSDB_Dividend_EUR(t,:); ...
                                       CSDB_Coupon_EUR(t,:); ... 
                                       CSDB_AccInterest_EUR(t,:)])';                                
end

CSDB_DirtyPrice1_EUR(CSDB_DirtyPrice1_EUR==0) = NaN;
CSDB_DirtyPrice2_EUR(CSDB_DirtyPrice2_EUR==0) = NaN;
CSDB_Return_EUR = [NaN(1,Nisins); (CSDB_DirtyPrice2_EUR(2:end,:)-CSDB_DirtyPrice1_EUR(1:end-1,:))./CSDB_DirtyPrice1_EUR(1:end-1,:)];
clear CSDB_DirtyPrice* t;

CSDB_Return_EUR(isinf(abs(CSDB_Return_EUR))) = NaN;
CSDB_Return_CleanPrice_EUR(isinf(abs(CSDB_Return_CleanPrice_EUR))) = NaN;

tt = find(umonth < min(All_Results.DATUM) | umonth > max(All_Results.DATUM));
CSDB_Return_EUR(tt,:) = [];
CSDB_Return_CleanPrice_EUR(tt,:) = [];
umonth(tt) = [];
Tmonth  = length(umonth);

keep All_Results CSDB_Return_CleanPrice_EUR CSDB_Return_EUR umonth uwpkenn_all;

%%%%%

isinmonth_ifs   = strcat(string(All_Results.DATUM),string(All_Results.ISIN));
isinmonth_csdb  = vect(strcat(string(repmat(umonth,1,length(uwpkenn_all))),repmat(uwpkenn_all',length(umonth),1)));

[~,idxWhereISINMonth] = ismember(isinmonth_ifs,isinmonth_csdb);

All_Results.Return_CleanPrice_EUR = NaN(height(All_Results),1);
All_Results.Return_CleanPrice_EUR(idxWhereISINMonth>0) = CSDB_Return_CleanPrice_EUR(idxWhereISINMonth(idxWhereISINMonth>0));

All_Results.Return_EUR = NaN(height(All_Results),1);
All_Results.Return_EUR(idxWhereISINMonth>0) = CSDB_Return_EUR(idxWhereISINMonth(idxWhereISINMonth>0));

keep All_Results

writetable(All_Results, strcat(projectPath, 'Data\SecurityLevelEffects\SecurityLevel_Returns.txt'));